from __future__ import annotations
from typing import Optional

class Config:
    # Server 服务器配置
    SERVER_HOST: str = "127.0.0.1"  # 服务器主机地址
    SERVER_PORT: int = 8000         # 服务器端口

    # MongoDB 配置
    MONGO_URI: str = "mongodb://127.0.0.1:27017/"  # MongoDB连接地址
    MONGO_DB: str = "ai_joker"                     # 数据库名
    MONGO_JOKES_COL: str = "jokes"                 # 笑话数据集合名
    MONGO_CHAT_COL: str = "chat_history"           # 聊天历史集合名
    MONGO_SOCKET_TIMEOUT_MS: int = 5000            # 连接超时时间(毫秒)

    # Milvus 向量数据库配置
    MILVUS_CONN: str = "joke_ai"       # 连接名称
    MILVUS_HOST: str = "127.0.0.1"     # 主机地址
    MILVUS_PORT: str = "19530"         # 端口
    MILVUS_COLLECTION: str = "jokes"   # 向量集合名

    # 嵌入模型配置（用于文本转向量）
    EMBED_MODEL: str = "sentence-transformers/all-MiniLM-L6-v2"  # 模型名称
    EMBED_DIM: int = 384                                         # 向量维度

    # 生成模型及参数（用于文本生成，如生成笑话）
    GEN_MODEL_NAME: str = "Qwen/Qwen2-0.5B-Instruct"  # 模型名称
    GEN_MAX_NEW_TOKENS: int = 96                       # 最大生成 tokens 数
    GEN_TEMPERATURE: float = 0.7                       # 温度系数（控制随机性）
    GEN_TOP_P: float = 0.9                             # 采样概率阈值
    GEN_REPETITION_PENALTY: float = 1.08               # 重复惩罚系数
    GEN_CONCURRENCY: int = 2                           # 并发数

    # 超时配置（秒）
    SEARCH_TIMEOUT_S: float = 3.5   # 搜索超时时间
    INFER_TIMEOUT_S: float = 20     # 推理超时时间

    # Milvus 索引/搜索参数
    MILVUS_INDEX_TYPE: str = "IVF_FLAT"  # 索引类型
    MILVUS_METRIC_TYPE: str = "COSINE"   # 距离度量方式（余弦相似度）
    MILVUS_NLIST: int = 128              # 索引聚类数
    MILVUS_NPROBE: int = 10              # 搜索时探查的聚类数

    # 数据导入配置
    IMPORT_BATCH_SIZE: int = 500  # 批量导入大小

    # 懒加载单例（首次访问时初始化）
    _mongo_client = None
    _mongo_db = None

    @classmethod
    def get_mongo_client(cls):
        from pymongo import MongoClient
        if cls._mongo_client is None:
            cls._mongo_client = MongoClient(
                cls.MONGO_URI,
                socketTimeoutMS=cls.MONGO_SOCKET_TIMEOUT_MS,
                serverSelectionTimeoutMS=cls.MONGO_SOCKET_TIMEOUT_MS,
            )
        return cls._mongo_client

    @classmethod
    def get_mongo_db(cls):
        if cls._mongo_db is None:
            cls._mongo_db = cls.get_mongo_client()[cls.MONGO_DB]
        return cls._mongo_db

    @classmethod
    def jokes_collection(cls):
        return cls.get_mongo_db()[cls.MONGO_JOKES_COL]

    @classmethod
    def chat_collection(cls):
        return cls.get_mongo_db()[cls.MONGO_CHAT_COL]

    @classmethod
    def milvus_connect(cls):
        from pymilvus import connections
        try:
            connections.connect(cls.MILVUS_CONN, host=cls.MILVUS_HOST, port=cls.MILVUS_PORT)
        except Exception:
            # 已连接则忽略
            pass
        return cls.MILVUS_CONN

    @classmethod
    def milvus_collection(cls):
        from pymilvus import Collection
        using = cls.milvus_connect()
        col = Collection(cls.MILVUS_COLLECTION, using=using)
        try:
            col.load()
        except Exception:
            pass
        return col

    @classmethod
    def get_embedder(cls):
        from sentence_transformers import SentenceTransformer
        return SentenceTransformer(cls.EMBED_MODEL)